package cn.wolfcode.service.impl;

import cn.wolfcode.common.exception.BusinessException;
import cn.wolfcode.domain.AccountLog;
import cn.wolfcode.domain.AccountTransaction;
import cn.wolfcode.domain.OperateIntegralVo;
import cn.wolfcode.mapper.AccountLogMapper;
import cn.wolfcode.mapper.AccountTransactionMapper;
import cn.wolfcode.mapper.UsableIntegralMapper;
import cn.wolfcode.service.IUsableIntegralService;
import cn.wolfcode.web.msg.IntergralCodeMsg;
import com.alibaba.fastjson.JSON;
import io.seata.rm.tcc.api.BusinessActionContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;


@Service
@Slf4j
public class UsableIntegralServiceImpl implements IUsableIntegralService {
    @Autowired
    private UsableIntegralMapper usableIntegralMapper;
    @Autowired
    private AccountTransactionMapper accountTransactionMapper;
    @Autowired
    private AccountLogMapper accountLogMapper;

    @Override
    public void decrIntegral(OperateIntegralVo operateIntegralVo) {
        // 插入流水记录 t_account_log插入
        AccountLog accountLog = new AccountLog();
        accountLog.setPkValue(operateIntegralVo.getPk());       // 订单编号
        accountLog.setType(AccountLog.TYPE_DECR);               // 积分变更类型(此处为减积分)
        accountLog.setAmount(operateIntegralVo.getValue());     // 变动金额
        accountLog.setGmtTime(new Date());                      // 日志插入时间
        accountLog.setInfo(operateIntegralVo.getInfo());        // 备注信息
        accountLogMapper.insert(accountLog);

        // 减少积分 t_usable_integral
        int amount=usableIntegralMapper.decrIntegral(operateIntegralVo.getUserId(),operateIntegralVo.getValue());
        if (amount == 0) {
            throw new BusinessException(IntergralCodeMsg.INTERGRAL_NOT_ENOUGH);     // 积分余额不足
        }
    }

    @Override
    @Transactional
    public void incrIntegral(OperateIntegralVo operateIntegralVo) {
        // 1.插入流水记录 t_account_log插入
        AccountLog accountLog = new AccountLog();
        accountLog.setPkValue(operateIntegralVo.getPk());
        accountLog.setType(AccountLog.TYPE_INCR);
        accountLog.setAmount(operateIntegralVo.getValue());
        accountLog.setGmtTime(new Date());
        accountLog.setInfo(operateIntegralVo.getInfo());
        accountLogMapper.insert(accountLog);

        // 2.增加积分 t_usable_integral
        usableIntegralMapper.addIntergral(operateIntegralVo.getUserId(),operateIntegralVo.getValue());
    }

    // 抽取t_account_transaction表中插入数据代码
    public void commonInsertTransaction(OperateIntegralVo operateIntegralVo, BusinessActionContext context,Integer state,String type) {
        AccountTransaction accountTransaction = new AccountTransaction();
        accountTransaction.setTxId(context.getXid());
        accountTransaction.setActionId(context.getBranchId()+"");
        accountTransaction.setUserId(operateIntegralVo.getUserId());
        accountTransaction.setGmtCreated(new Date());
        accountTransaction.setGmtModified(new Date());
        accountTransaction.setAmount(operateIntegralVo.getValue());
        accountTransaction.setType(type);
        accountTransaction.setState(state);
        accountTransactionMapper.insert(accountTransaction);
    }


    @Override
    public void incrIntegralTry(OperateIntegralVo operateIntegralVo, BusinessActionContext context) {
        log.info("------进入加积分try------");
        commonInsertTransaction(operateIntegralVo,context,AccountTransaction.STATE_TRY,AccountTransaction.TYPE_INCR);

    }

    @Override
    public void incrIntegralCommit(BusinessActionContext context) {
        log.info("------进入加积分confirm------");
        AccountTransaction accountTransaction = accountTransactionMapper.get(context.getXid(), context.getBranchId() + "");
        if (accountTransaction == null) {
            log.info("异常情况");
        }

        if (AccountTransaction.STATE_TRY.equals(accountTransaction.getState())) {
            Object objJson = context.getActionContext("operateIntegralVo");
            OperateIntegralVo operateIntegralVo = JSON.parseObject(objJson.toString(), OperateIntegralVo.class);
            // 正常执行confirm逻辑    增加积分
            usableIntegralMapper.addIntergral(operateIntegralVo.getUserId(),operateIntegralVo.getValue());
            // 将状态修改成已提交状态
            accountTransactionMapper.updateAccountTransactionState(
                    context.getXid(), context.getBranchId()+"",
                    AccountTransaction.STATE_COMMIT, AccountTransaction.STATE_TRY);
        } else if (AccountTransaction.STATE_COMMIT.equals(accountTransaction.getState())) {
            // 什么都不做 处理幂等性
        } else {
            log.info("异常情况");
        }
    }

    @Override
    public void incrIntegralRollback(BusinessActionContext context) {
        log.info("------进入加积分cancel------");
        AccountTransaction accountTransaction = accountTransactionMapper.get(context.getXid(), context.getBranchId() + "");
        if (accountTransaction == null) {
            // 在t_account_transaction表中插入数据
            Object objJson = context.getActionContext("operateIntegralVo");
            OperateIntegralVo operateIntegralVo = JSON.parseObject(objJson.toString(), OperateIntegralVo.class);
            commonInsertTransaction(operateIntegralVo,context,AccountTransaction.STATE_CANCEL,AccountTransaction.TYPE_INCR);
        }

        if (AccountTransaction.STATE_TRY.equals(accountTransaction.getState())) {
            // 进行cancel逻辑
            // 将状态修改为已回滚的状态
            accountTransactionMapper.updateAccountTransactionState(context.getXid(), context.getBranchId()+"", AccountTransaction.STATE_CANCEL, AccountTransaction.STATE_TRY);
        } else if (AccountTransaction.STATE_CANCEL.equals(accountTransaction.getState())) {
            // 什么都不做 处理幂等性
        } else {
            log.info("异常情况");
        }

    }


    @Override
    public void decrIntegralTry(OperateIntegralVo operateIntegralVo, BusinessActionContext context) {
        log.info("------进入减积分try------");
        // 往事务控制表中插入数据
        commonInsertTransaction(operateIntegralVo,context,AccountTransaction.STATE_TRY,AccountTransaction.TYPE_DECR);
        int count = usableIntegralMapper.freezeIntergral(operateIntegralVo.getUserId(), operateIntegralVo.getValue());
        if (count==0) {
            throw new BusinessException(IntergralCodeMsg.OP_INTERGRAL_ERROR);
        }
    }

    @Override
    public void decrIntegralCommit(BusinessActionContext context) {
        log.info("------进入减积分confirm------");
        // 查询事务控制表中是否有数据 (t_account_transaction)
       AccountTransaction accountTransaction = accountTransactionMapper.get(context.getXid(), context.getBranchId() + "");
        if (accountTransaction==null) {
            log.info("异常情况");
        }
        if (AccountTransaction.STATE_TRY.equals(accountTransaction.getState())) {

            Object objVo = context.getActionContext("operateIntegralVo");
            OperateIntegralVo operateIntegralVo = JSON.parseObject(objVo.toString(), OperateIntegralVo.class);
            // 执行confirm逻辑 扣除金额
            int count = usableIntegralMapper.commitChange(operateIntegralVo.getUserId(), operateIntegralVo.getValue());
            if (count==0) {
                throw new BusinessException(IntergralCodeMsg.OP_INTERGRAL_ERROR);
            }
            // 将状态修改成已提交状态
            accountTransactionMapper.updateAccountTransactionState(context.getXid(), context.getBranchId()+"",
                    AccountTransaction.STATE_COMMIT, AccountTransaction.STATE_TRY);

        } else if (AccountTransaction.STATE_COMMIT.equals(accountTransaction.getState())) {
            // 执行幂等性 返回成功
        } else {
            log.info("异常情况");
        }

    }

    @Override
    public void decrIntegralRollback(BusinessActionContext context) {
        log.info("------进入减积分cancel------");
        Object objVo = context.getActionContext("operateIntegralVo");
        OperateIntegralVo operateIntegralVo = JSON.parseObject(objVo.toString(), OperateIntegralVo.class);
        AccountTransaction accountTransaction = accountTransactionMapper.get(context.getXid(), context.getBranchId()+"");
        if (accountTransaction==null) {
            // 插入事务控制表记录

            commonInsertTransaction(operateIntegralVo,context,AccountTransaction.STATE_CANCEL,AccountTransaction.TYPE_DECR);
        }
        if (AccountTransaction.STATE_TRY.equals(accountTransaction.getState())) {
            // 继续执行cancel方法
            // 将状态修改为已回滚状态
            usableIntegralMapper.unFreezeIntergral(operateIntegralVo.getUserId(),operateIntegralVo.getValue());
            accountTransactionMapper.updateAccountTransactionState(context.getXid(),context.getBranchId()+"",AccountTransaction.STATE_CANCEL,AccountTransaction.STATE_TRY);
        } else if (AccountTransaction.STATE_CANCEL.equals(accountTransaction.getState())) {
            // 什么都不做 处理幂等性
        } else {
            log.info("异常情况");
        }
    }
}
